//=========================================================================== // CONWAY'S GAME OF LIFE // Version 23 FAST // 19 September 2012 // Nick Gessler // Fast: using TBitmap //=========================================================================== #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //=========================================================================== // DEFINES //=========================================================================== #define DEAD 0 #define ALIVE 1 #define RANDOM 2 #define REMEMBEREDWORLD 3 //=========================================================================== // VARIABLES //=========================================================================== bool thisWorld[100][100]; bool nextWorld[100][100]; bool rememberedWorld[100][100]; bool stop = true; int iterations; int e, s; // east & south coordinates of a cell or agent int nE, nS; // east & south coordinates of a neighbor of that cell int livingNeighbors; Graphics::TBitmap* worldBMP = new Graphics::TBitmap(); //=========================================================================== // FUNCTIONS //=========================================================================== //------------------------ make coordinate valid for a toroidal wrapped world int w (int coordinate) { return (100 + coordinate) % 100; } //----------------------------------------------------------- Show This World void showThisWorld (void) { for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { if (thisWorld[i][j] == DEAD) { worldBMP->Canvas->Brush->Color = clRed; worldBMP->Canvas->Pen->Color = clRed; } if (thisWorld[i][j] == ALIVE) { worldBMP->Canvas->Brush->Color = clLime; worldBMP->Canvas->Pen->Color = clLime; } worldBMP->Canvas-> Rectangle(i * 5, j * 5, i * 5 + 5, j * 5 + 5); } } Form1->PaintBox1->Canvas->Draw(0, 0, worldBMP); } //------------------------------------------------------------- Show Changes void showChanges (void) { for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { if (thisWorld[i][j] != nextWorld[i][j]) { if (nextWorld[i][j] == DEAD) { worldBMP->Canvas->Brush->Color = clRed; worldBMP->Canvas->Pen->Color = clRed; } if (nextWorld[i][j] == ALIVE) { worldBMP->Canvas->Brush->Color = clLime; worldBMP->Canvas->Pen->Color = clLime; } worldBMP->Canvas-> Rectangle(i * 5, j * 5, i * 5 + 5, j * 5 + 5); } } } Form1->PaintBox1->Canvas->Draw(0, 0, worldBMP); } //-------------------------------------------------------------------- Reset void reset (int choice) { iterations = 0; for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { if (choice == RANDOM) { thisWorld[i][j] = random(2); } if (choice == DEAD) { thisWorld[i][j] = DEAD; } if (choice == REMEMBEREDWORLD) { thisWorld[i][j] = rememberedWorld[i][j]; } } } showThisWorld(); Form1->EditIterations->Text = iterations; } //---------------------------------------- Copy thisWorld to rememberedWorld void copyThisWorldToRememberedWorld (void) { for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { rememberedWorld[i][j] = thisWorld[i][j]; } } } //---------------------------------------------- Copy nextWorld to thisWorld void copyNextWorldToThisWorld (void) { for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { thisWorld[i][j] = nextWorld[i][j]; } } } //--------------------------------------------------- Count Living Neighbors int countLivingNeighbors (void) { int neighbors = 0; for (nE = e - 1; nE <= e + 1; nE++) { for (nS = s -1; nS <= s + 1; nS++) { if (nE == e && nS == s) { continue; } if (thisWorld[w(nE)][w(nS)] == ALIVE) { neighbors++; } } } return neighbors; } //------------------------------------------------------- Compute Next World void computeNextWorld (void) { for (e = 0; e < 100; e++) { for (s = 0; s < 100; s++) { livingNeighbors = countLivingNeighbors(); switch (thisWorld[e][s]) { case DEAD: if (livingNeighbors == 3) { nextWorld[e][s] = ALIVE; } else { nextWorld[e][s] = DEAD; } break; case ALIVE: if (livingNeighbors == 3 || livingNeighbors == 2) { nextWorld[e][s] = ALIVE; } else { nextWorld[e][s] = DEAD; } break; } } } } //--------------------------------------------------------------------- Step void step (void) { iterations++; computeNextWorld(); showChanges(); copyNextWorldToThisWorld(); Form1->EditIterations->Text = iterations; } //---------------------------------------------------------------------- Run void run (void) { if (iterations == 0) { copyThisWorldToRememberedWorld(); } while(stop == false) { step(); Application->ProcessMessages(); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { randomize(); reset(RANDOM); worldBMP->Height = Form1->PaintBox1->Height; worldBMP->Width = Form1->PaintBox1->Width; } //---------------------------------------------------------------- Form Paint void __fastcall TForm1::FormPaint(TObject *Sender) { showThisWorld(); } //------------------------------------------------------- PaintBox Mouse Down void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { thisWorld[X/5][Y/5] = !thisWorld[X/5][Y/5]; showThisWorld(); } //---------------------------------------------------------------- Run Button void __fastcall TForm1::ButtonRunClick(TObject *Sender) { stop = false; run(); } //--------------------------------------------------------------- Step Button void __fastcall TForm1::ButtonStepClick(TObject *Sender) { stop = true; // do we really need this? step(); } //--------------------------------------------------------------- Stop Button void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; } //------------------------------------------------------- Reset Random Button void __fastcall TForm1::ButtonRandomClick(TObject *Sender) { reset(RANDOM); } //--------------------------------------------------------- Reset Dead Button void __fastcall TForm1::ButtonDeadClick(TObject *Sender) { reset(DEAD); } //----------------------------------------------------- Reset Remember Button void __fastcall TForm1::ButtonRememberClick(TObject *Sender) { reset(REMEMBEREDWORLD); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { delete worldBMP; } //---------------------------------------------------------------------------